package controller

import (
	"strconv"

	json "github.com/bytedance/sonic"

	"fiber-demo/internal/common"
	"fiber-demo/internal/model/entity"
	"fiber-demo/internal/service"
	"github.com/gofiber/fiber/v3"
)

type UserController struct{}

var UserControllerInstance = UserController{}

// List
// @Description get user list
// @Summary get user list
// @Tags User
// @Accept json
// @Produce json
// @Success 200 {object} map[string]any
// @Router /user [get]
func (c *UserController) List(ctx fiber.Ctx) error {
	list, err := service.UserServiceInstance.List()
	if err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	return ctx.JSON(common.NewResponseBuilder().Data(list).Build())
}

// One
// @Description get user by id
// @Summary get user by id
// @Tags User
// @Accept json
// @Produce json
// @Param id path integer true "User ID"
// @Success 200 {object} map[string]any
// @Router /user/{id} [get]
func (c *UserController) One(ctx fiber.Ctx) (err error) {
	id, err := strconv.Atoi(ctx.Params("id"))
	if err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	one, err := service.UserServiceInstance.One(id)
	if err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	return ctx.JSON(common.NewResponseBuilder().Data(one).Build())
}

// Add
// @Description adds a user
// @Summary adds a user
// @Tags User
// @Accept json
// @Produce json
// @Param user body entity.User true "user"
// @Success 200 {object} map[string]any
// @Router /user [post]
func (c *UserController) Add(ctx fiber.Ctx) error {
	user := new(entity.User)
	bytes := ctx.Body()
	if err := json.Unmarshal(bytes, user); err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	if err := service.UserServiceInstance.Add(*user); err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	return ctx.JSON(common.NewResponseBuilder().Build())
}

// Modify
// @Description modifies a user
// @Summary modifies a user
// @Tags User
// @Accept json
// @Produce json
// @Param user body entity.User true "user"
// @Success 200 {object} map[string]any
// @Router /user [put]
func (c *UserController) Modify(ctx fiber.Ctx) error {
	user := new(entity.User)
	bytes := ctx.Body()
	if err := json.Unmarshal(bytes, user); err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	if err := service.UserServiceInstance.Modify(*user); err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	return ctx.JSON(common.NewResponseBuilder().Build())
}

// Delete
// @Description remove user by id
// @Summary remove user by id
// @Tags User
// @Accept json
// @Produce json
// @Param id path integer true "User ID"
// @Success 200 {object} map[string]any
// @Router /user/{id} [delete]
func (c *UserController) Delete(ctx fiber.Ctx) error {
	id, err := strconv.Atoi(ctx.Params("id"))
	if err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	if err = service.UserServiceInstance.Delete(id); err != nil {
		return ctx.JSON(common.NewResponseBuilder().ErrorMessage(err).Build())
	}
	return ctx.JSON(common.NewResponseBuilder().Build())
}
